package com.example.emos.wx.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.example.emos.wx.db.mapper.*;
import com.example.emos.wx.db.pojo.MessageEntity;
import com.example.emos.wx.db.pojo.TbUser;
import com.example.emos.wx.exception.EmosException;
import com.example.emos.wx.service.UserService;
import com.example.emos.wx.task.ActiveCodeTask;
import com.example.emos.wx.task.EmailTask;
import com.example.emos.wx.task.MessageTask;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @ClassName UserServiceImpl
 * @Description TODO
 * @Author daoketa
 * @Version 1.0
 **/
@Service
@Slf4j
@Scope("prototype")
public class UserServiceImpl implements UserService {

    private static final String URL = "https://api.weixin.qq.com/sns/jscode2session";

    @Value("${wx.app-id}")
    private String appId;

    @Value("${wx.app-secret}")
    private String appSecret;

    @Autowired
    private TbUserMapper userMapper;

    @Autowired
    private TbDeptMapper deptMapper;

    @Autowired
    private MessageDao messageDao;

    @Autowired
    private MessageRefDao messageRefDao;

    @Autowired
    private TbCheckinMapper checkinMapper;

    @Autowired
    private TbFaceModelMapper faceModelMapper;

    @Autowired
    private MessageTask messageTask;

    @Autowired
    private ActiveCodeTask activeCodeTask;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * appid	小程序唯一标识
     * secret	小程序密钥
     * js_code	临时授权字符串
     * grant_type	authorization_code
     * @author daoketa
     * @param
     */
    private String getOpenId(String tempCode){
        HashMap hashmap = new HashMap();
        hashmap.put("appid", appId);
        hashmap.put("secret", appSecret);
        hashmap.put("js_code", tempCode);
        hashmap.put("grant_type", "authorization_code");
        String resp = HttpUtil.post(URL, hashmap);
        JSONObject json = JSONUtil.parseObj(resp);
        String openid = json.getStr("openid");
        if (openid == null || openid.length() == 0){
            throw new RuntimeException("临时登录凭证失效");
        }
        return openid;
    }


    /**
     * 注册用户，返回用户 id 用于生成 token
     * @author daoketa
     * @param
     */
    @Override
    public Integer registerUser(String activationCode, String tempCode, String nickname, String photo) {
        /** 查看激活码，判断是否属于管理员注册 */
        if ("000000".equals(activationCode)){
            /** 判断管理员是否已注册 */
            boolean isRegister = userMapper.isRegisterRoot();
            if (!isRegister){
                /** 把当前用户绑定到 ROOT 帐户 */
                String openId = getOpenId(tempCode);
                HashMap param = new HashMap();
                param.put("openId", openId);
                param.put("nickname", nickname);
                param.put("photo", photo);
                param.put("role", "[0]");
                param.put("status", 1);
                param.put("createTime", new Date());
                param.put("root", true);
                userMapper.insertUser(param);
                Integer id = userMapper.selectByOpenId(openId);
                /** 注册后发送系统消息 */
                MessageEntity messageEntity = new MessageEntity();
                messageEntity.setSenderId(0);
                messageEntity.setSenderName("系统消息");
                messageEntity.setUuid(IdUtil.simpleUUID());
                messageEntity.setMsg("欢迎您注册成为超级管理员，请及时更新你的员工个人信息。");
                messageEntity.setSendTime(new Date());
                messageTask.sendAsync(id+"", messageEntity);
                return id;
            }else {
                throw new EmosException("管理员已注册!无法绑定管理员账号!");
            }
        }else if(!redisTemplate.hasKey(activationCode)){
            throw new EmosException("激活码无效");
        }else {
            Integer userId = Integer.valueOf(redisTemplate.opsForValue().get(activationCode).toString());

            /** 补充新员工剩余信息 */
            String openId = getOpenId(tempCode);
            HashMap param = new HashMap();
            param.put("openId", openId);
            param.put("nickname", nickname);
            param.put("photo", photo);
            param.put("userId",userId);
            Integer rows = userMapper.activeUserAccount(param);
            if (rows != 1){
                throw new EmosException("新员工注册失败");
            }

            /** 删除 redis 中的激活码 */
            redisTemplate.delete(activationCode);

            /** 注册成功发送消息 */
            MessageEntity messageEntity = new MessageEntity();
            messageEntity.setSenderId(0);
            messageEntity.setSenderName("系统消息");
            messageEntity.setSendTime(new Date());
            messageEntity.setUuid(UUID.randomUUID().toString());
            messageEntity.setMsg("欢迎您注册");
            messageTask.sendAsync(userId.toString(), messageEntity);
            return userId;
        }
    }

    /**
     * 用户登录
     * @author daoketa
     * @param
     */
    @Override
    public Integer login(String tempCode) {
        String openId = this.getOpenId(tempCode);
        Integer userId = userMapper.selectByOpenId(openId);
        if (userId == null){
            throw new EmosException("账户不存在");
        }
        /** 从消息队列中接收消息，转移到消息表 */
        messageTask.receiveAysnc(userId+"");
        return userId;
    }

    /**
     * 查询用户权限列表
     * @author daoketa
     * @param
     */
    @Override
    public Set<String> searchUserPermissions(Integer userId) {
        Set<String> permissions = userMapper.searchUserPermissions(userId);
        return permissions;
    }

    @Override
    public TbUser selectById(Integer userId) {
        TbUser user = userMapper.selectById(userId);
        if(user == null){
            log.error("用户不存在!");
        }
        return user;
    }

    @Override
    public String searchUserHiredate(Integer userId) {
        String hiredate = userMapper.searchUserHiredate(userId);
        return hiredate;
    }

    @Override
    public HashMap searchUserSummary(Integer userId) {
        HashMap map = userMapper.searchUserSummary(userId);
        return map;
    }

    /**
     * 查询所有部门成员列表
     * @author daoketa
     * @param
     */
    @Override
    public ArrayList<HashMap> searchUserGroupByDept(String keyword) {
        ArrayList<HashMap> list_1 = deptMapper.searchDeptMembers(keyword);
        ArrayList<HashMap> list_2 = userMapper.searchUserGroupByDept(keyword);
        for (HashMap map_1: list_1) {
            long deptId_1 =(long) map_1.get("id");
            ArrayList members = new ArrayList();
            for (HashMap map_2: list_2) {
                long deptId_2 =(long) map_2.get("deptId");
                if (deptId_2==deptId_1){
                    members.add(map_2);
                }
            }
            map_1.put("members", members);
        }
        return list_1;
    }

    /**
     * 查询会议成员信息
     * @author daoketa
     * @param
     */
    @Override
    public ArrayList<HashMap> searchMembers(List param) {
        ArrayList<HashMap> list = userMapper.searchMembers(param);
        return list;
    }

    @Override
    public List<HashMap> searchUserNameAndPhoto(List param) {
        List<HashMap> list = userMapper.searchUserNameAndPhoto(param);
        return list;
    }

    @Override
    public String searchUserEmail(Integer userId){
        String email = userMapper.searchUserEmail(userId);
        return email;
    }

    @Override
    public JSONObject searchUserContactList() {
        ArrayList<HashMap> list = userMapper.searchUserContactList();
        String letter = null;
        JSONObject json = new JSONObject(true);
        JSONArray array = null;
        /** 取出首字母，所有名字按照首字母分组 */
        for(HashMap<String, String> map : list){
            String name = map.get("name");
            String firstLetter = PinyinUtil.getPinyin(name).charAt(0) + "";
            firstLetter = firstLetter.toUpperCase();
            if (letter == null || !letter.equals(firstLetter)){
                letter = firstLetter;
                array = new JSONArray();
                json.set(letter, array);
            }
            array.put(map);
        }
        return json;
    }

    @Override
    public Integer searchUserIdByEmail(String email) {
        Integer userId = userMapper.searchUserIdByEmail(email);
        return userId;
    }

    @Override
    public HashMap searchUserInfo(Integer userId) {
        HashMap hashMap = userMapper.searchUserInfo(userId);
        return hashMap;
    }

    @Override
    public void insertUser(HashMap param) {
        Integer rows = userMapper.insertUser(param);
        if (rows != 1){
            throw new EmosException("添加新员工失败");
        }else {
            /** 发送激活码到新员工邮箱 */
            String email = param.get("email").toString();
            Integer userId = userMapper.searchUserIdByEmail(email);
            activeCodeTask.sendActiveCodeAsync(userId, email);
        }
    }



    @Override
    public Integer updateUserInfo(HashMap param) {
        Integer rows = userMapper.updateUserInfo(param);
        if(rows != 1){
            throw new EmosException("更新用户信息失败");
        }else {
            //更新成功就发送消息通知
            Integer userId = (Integer) param.get("userId");
            String msg = "您的个人资料已经被成功修改";
            MessageEntity entity = new MessageEntity();
            entity.setSenderId(0);  //系统自动发出
            entity.setSenderPhoto("https://static-1258386385.cos.ap-beijing.myqcloud.com/img/System.jpg");
            entity.setSenderName("系统消息");
            entity.setMsg(msg);
            entity.setSendTime(new Date());
            messageTask.sendAsync(userId.toString(), entity);
        }
        return rows;
    }

    @Override
    public void deleteUserById(Integer id) {
        Integer rows = userMapper.deleteUserById(id);
        if (rows != 1){
            throw new EmosException("删除员工失败");
        }

        messageRefDao.deleteUserMessageRef(id);
        messageDao.deleteUserMessage(id);
        checkinMapper.deleteUserCheckin(id);
        faceModelMapper.deleteFaceModel(id);
        messageTask.deleteQueue(id+"");
    }


}
